<html>
<head><meta charset="utf-8"><title>stacked borrows violation in VecDeque · t-lang/wg-unsafe-code-guidelines · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/index.html">t-lang/wg-unsafe-code-guidelines</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked.20borrows.20violation.20in.20VecDeque.html">stacked borrows violation in VecDeque</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="136784480"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked%20borrows%20violation%20in%20VecDeque/near/136784480" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked.20borrows.20violation.20in.20VecDeque.html#136784480">(Oct 30 2018 at 15:35)</a>:</h4>
<p>The one remaining stacked borrows violation in the test suite is rather interesting. It appears when using <code>VecDeque::drain</code>, but the actual problem is <code>NonNull::from(&amp;mut T)</code>. That looks as follows:</p>
<div class="codehilite"><pre><span></span><span class="k">impl</span><span class="o">&lt;</span><span class="na">&#39;a</span><span class="p">,</span><span class="w"> </span><span class="n">T</span>: <span class="o">?</span><span class="nb">Sized</span><span class="o">&gt;</span><span class="w"> </span><span class="nb">From</span><span class="o">&lt;&amp;</span><span class="na">&#39;a</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">T</span><span class="o">&gt;</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">NonNull</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">fn</span> <span class="nf">from</span><span class="p">(</span><span class="n">reference</span>: <span class="kp">&amp;</span><span class="na">&#39;a</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">T</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">Self</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="n">NonNull</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">pointer</span>: <span class="nc">NonZero</span><span class="p">(</span><span class="n">reference</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="n">_</span><span class="p">)</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</pre></div>


<p>Looks innocent, doesn't it? What actually happens in MIR, however, is...</p>
<div class="codehilite"><pre><span></span>_6 = &amp;(*_1)
_5 = move _6 as *const T (Misc)
...
</pre></div>


<p>IOW, we turn the mutable ref into a shared one, and then turn that into a raw (const) ptr and go from there. WAY later, we end up writing through this reference, and my model says "nope, you cannot write through this because you got it from a shared ref".</p>



<a name="136784553"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked%20borrows%20violation%20in%20VecDeque/near/136784553" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked.20borrows.20violation.20in.20VecDeque.html#136784553">(Oct 30 2018 at 15:36)</a>:</h4>
<p>Funny enough, the distinction between <code>*mut</code> and <code>*const</code> -- which was meant to help -- actually turns out to be harmful here.</p>



<a name="136791654"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked%20borrows%20violation%20in%20VecDeque/near/136791654" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked.20borrows.20violation.20in.20VecDeque.html#136791654">(Oct 30 2018 at 17:17)</a>:</h4>
<p>:)</p>



<a name="136791664"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked%20borrows%20violation%20in%20VecDeque/near/136791664" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked.20borrows.20violation.20in.20VecDeque.html#136791664">(Oct 30 2018 at 17:18)</a>:</h4>
<p>I suppose there is no <em>particular</em> reason for the cast to work that way</p>



<a name="136791934"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked%20borrows%20violation%20in%20VecDeque/near/136791934" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked.20borrows.20violation.20in.20VecDeque.html#136791934">(Oct 30 2018 at 17:21)</a>:</h4>
<p>true</p>



<a name="136791946"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked%20borrows%20violation%20in%20VecDeque/near/136791946" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked.20borrows.20violation.20in.20VecDeque.html#136791946">(Oct 30 2018 at 17:21)</a>:</h4>
<p>but it also shows the dangers of making implicit operations like coercions carry semantic meaning</p>



<a name="136791952"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked%20borrows%20violation%20in%20VecDeque/near/136791952" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked.20borrows.20violation.20in.20VecDeque.html#136791952">(Oct 30 2018 at 17:21)</a>:</h4>
<p>yet, I am fairly sure we want the mut-to-shared-ref cast to have semantic meaning</p>



<a name="136792003"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked%20borrows%20violation%20in%20VecDeque/near/136792003" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked.20borrows.20violation.20in.20VecDeque.html#136792003">(Oct 30 2018 at 17:22)</a>:</h4>
<p>we should probably "just" change inference to avoid introducing such casts unless it absolutely has to...</p>



<a name="136792412"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked%20borrows%20violation%20in%20VecDeque/near/136792412" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked.20borrows.20violation.20in.20VecDeque.html#136792412">(Oct 30 2018 at 17:28)</a>:</h4>
<p>hm, changing just that cast is not enough to make the test pass... seems like I will have to investigate some more</p>



<a name="136792851"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked%20borrows%20violation%20in%20VecDeque/near/136792851" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked.20borrows.20violation.20in.20VecDeque.html#136792851">(Oct 30 2018 at 17:34)</a>:</h4>
<blockquote>
<p>but it also shows the dangers of making implicit operations like coercions carry semantic meaning</p>
</blockquote>
<p>confirm</p>



<a name="136794002"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked%20borrows%20violation%20in%20VecDeque/near/136794002" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked.20borrows.20violation.20in.20VecDeque.html#136794002">(Oct 30 2018 at 17:51)</a>:</h4>
<p>uh yeah I see what is going on... after creating the raw ptr, we call <code>self.buffer_as_mut_slice()</code></p>



<a name="136794008"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked%20borrows%20violation%20in%20VecDeque/near/136794008" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked.20borrows.20violation.20in.20VecDeque.html#136794008">(Oct 30 2018 at 17:51)</a>:</h4>
<p>so we use <code>self</code> again</p>



<a name="136794020"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked%20borrows%20violation%20in%20VecDeque/near/136794020" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked.20borrows.20violation.20in.20VecDeque.html#136794020">(Oct 30 2018 at 17:51)</a>:</h4>
<p>which kills the reborrows, including the raw one</p>



<a name="136796912"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked%20borrows%20violation%20in%20VecDeque/near/136796912" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked.20borrows.20violation.20in.20VecDeque.html#136796912">(Oct 30 2018 at 18:33)</a>:</h4>
<p>and this is not easy to fix, either... <code>buffer_as_mut_slice</code> returns a reference so we cannot create the <code>NonNull</code> <em>after</em> creating the slice, either. hm.</p>



<a name="146801303"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked%20borrows%20violation%20in%20VecDeque/near/146801303" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked.20borrows.20violation.20in.20VecDeque.html#146801303">(Nov 05 2018 at 15:06)</a>:</h4>
<p>I re-did a large chunk of the model, though the core stayed the same, fixing "partially interior mutable data" at <a href="https://github.com/RalfJung/miri/tree/new-interior-mut" target="_blank" title="https://github.com/RalfJung/miri/tree/new-interior-mut">https://github.com/RalfJung/miri/tree/new-interior-mut</a>. Interestingly that also fixed <code>VecDeque</code>. I still have to understand how and why.</p>



<a name="147245856"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked%20borrows%20violation%20in%20VecDeque/near/147245856" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked.20borrows.20violation.20in.20VecDeque.html#147245856">(Nov 07 2018 at 18:44)</a>:</h4>
<p>This now gets allowed because when we turn <code>&amp;mut</code> to <code>&amp;</code>, we first push a <code>Shr</code> ("shared" -&gt; accessible by raw ptrs) and then freeze</p>



<a name="147245880"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked%20borrows%20violation%20in%20VecDeque/near/147245880" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked.20borrows.20violation.20in.20VecDeque.html#147245880">(Nov 07 2018 at 18:45)</a>:</h4>
<p>then <code>NonNull::from</code> creates a raw ptr, and when we use that the freezing is dropped but the raw ptr remains usable</p>



<a name="147245901"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked%20borrows%20violation%20in%20VecDeque/near/147245901" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked.20borrows.20violation.20in.20VecDeque.html#147245901">(Nov 07 2018 at 18:45)</a>:</h4>
<p>I didn't <em>intend</em> to it this way but I have tos ay this seems to work quite well so I am inclined to leave it this way :D</p>



<a name="147247461"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked%20borrows%20violation%20in%20VecDeque/near/147247461" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nicole Mazzuca <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked.20borrows.20violation.20in.20VecDeque.html#147247461">(Nov 07 2018 at 19:07)</a>:</h4>
<p>huh, cool</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>